#!/bin/bash
##
## This file is maintained by Ansible - CHANGES WILL BE OVERWRITTEN
##

server=`hostname`
data='{{ postgresql_pgdata }}'
dir='{{ postgresql_backup_dir }}/current'
mailto='{{ postgresql_backup_mail_recipient }}'
mutex='{{ postgresql_backup_local_dir }}/scheduledmutex'
rotate='{{ postgresql_backup_rotate | default("True") }}'

[ '{{ postgresql_backup_remote_rsync_path | default("None") }}' != 'None' ] && remote_rsync='--rsync-path={{ postgresql_backup_remote_rsync_path }}' || remote_rsync=''

handler()
{
    command=$@
    out=`$command 2>&1`
    ret=$?
    if [ $ret -ne 0 -a ! \( $ret -eq 24 -a $1 = 'rsync' \) ]; then
        (echo "execuing $command failed with code $ret:" ; echo "$out") | mail -s "$server: Postgres scheduled backup failed" $mailto
        rm -f $mutex
        if [ "$backup_started" = 1 ]; then
            echo "SELECT pg_stop_backup();" | psql
        fi
        exit 1
    else
        if [ -n "$out" ]; then
            echo "$out"
        fi
    fi
}

psql_handler()
{
    sql=$@
    out=`echo "$sql" | psql 2>&1`
    ret=$?
    if [ $ret -ne 0 ]; then
        (echo "executing $sql failed with code $ret:" ; echo "$out") | mail -s "$server: Postgres scheduled backup failed" $mailto
        rm -f $mutex
        exit 1
    else
        probe=`echo "$out" | grep ERROR`
        ret=$?
        if [ $ret -eq 0 ]; then
            (echo "executing sql $sql failed:" ; echo "$out") | mail -s "$server: Postgres scheduled backup failed" $mailto
            rm -f $mutex
            exit 1
        #else
        #    if [ -n "$out" ]; then
        #        echo $out
        #    fi
        fi
    fi
}

[[ "$dir" == *':'* ]] && dir_is_remote=1
[ "$dir_is_remote" -a $rotate != "False" ] && { echo "error: rotation with remote backup directory is not implemented" | mail -s "$server: Postgres scheduled backup failed" $mailto ; exit 1 ; }

[ ! -d `dirname $mutex` ] && handler mkdir -p `dirname $mutex`

while [ -f $mutex ]; do
    sleep 5
done

start=`date +%s`

echo "scheduled $$" > $mutex

if [ ! "$dir_is_remote" ]; then
    # move previous backup
    if [ -d $dir -a $rotate = "True" ]; then
        handler mv $dir {{ postgresql_backup_dir }}/`date -u +%Y%m%dT%H%M%SZ`
    fi
fi

# tell postgres we'll be backing up
psql_handler "SELECT pg_start_backup('$dir');"
backup_started=1

# ensure the local wal/ directory exists, so rsync creates it for wal archival
handler mkdir -p $data/wal

# begin the backup
handler rsync $remote_rsync -rptg --delete --delete-delay --exclude pg_xlog $data/ $dir

# tell postgres we're done
psql_handler "SELECT pg_stop_backup();"

echo "Elapsed time: $(( `date +%s` - $start )) seconds" | mail -s "$server: Postgres scheduled backup succeeded" $mailto

# exit normally
rm -f $mutex
exit 0
